#!/bin/bash

DEFAULT_DIR="l4d2"
DEFAULT_IP="0.0.0.0"
DEFAULT_PORT="39615"
DEFAULT_MAP="c2m1_highway"
DEFAULT_MODE="coop"
DEFAULT_CFG="server.cfg"
DEFAULT_TICK="100"
START_PARAMETERS=" +sv_allow_votes 0 +sv_vote_issue_changelevel_allowed 0 +sv_vote_issue_restart_game_allowed 0 +sv_timeout 0 -strictportbind -insecure -nobreakpad -noassert -ip ${DEFAULT_IP} -port ${DEFAULT_PORT} +map ${DEFAULT_MAP} +mp_gamemode ${DEFAULT_MODE} +servercfgfile ${DEFAULT_CFG} -tickrate ${DEFAULT_TICK}"

STEAMCMD_URL="https://gitee.com/wwwwwddzafv/qs/raw/master/steamcmd.tar.gz"
STEAMCMD_QUICK_URI="https://raw.github.com/apples1949/SteamCMDLinuxFile/main/build/steamcmd_linux.tar.gz"

PLUGIN_VERSION=(-s -d -n)
DEFAULT_SH=$(cd $(dirname $0) && pwd)
folder_path=${DEFAULT_SH}/steamcmd/${DEFAULT_DIR}/JS-MODS
l4d2_menu=${DEFAULT_SH}/steamcmd/${DEFAULT_DIR}
plugins_name=${DEFAULT_DIR}_plugins.txt
progress_name=${DEFAULT_DIR}_progress.txt
selected_folders=()

if [ ! -e "$plugins_name" ]; then
	touch "$plugins_name"
fi

if [ ! -e "$progress_name" ]; then
	touch "$progress_name"
fi

function centos() {
	echo -e "\e[92m安装依赖...\e[0m"
	case "${VERSION_ID}" in
		7|8)
			sudo yum update
			sudo yum install glibc.i686 libstdc++.i686 curl screen zip unzip
		;;
		*)
			echo -e "\e[34m不支持的系统版本\e[0m \e[31m${VERSION_ID}\e[0m"
			exit 1
		;;
	esac

	if [ "${?}" -ne 0 ]; then
		echo -e "\e[31m依赖安装失败\e[0m"
		exit 1
	else
		echo -e "\e[92m依赖安装成功，开始安装服务器\e[0m"
	fi
}

function ubuntu() {
	echo -e "\e[92m安装依赖...\e[0m"
	sudo dpkg --add-architecture i386 && \
	sudo apt update && \
	case "${VERSION_ID}" in
		16.04|18.04|20.04)
			sudo apt -y install lib32gcc1 lib32stdc++6 lib32z1-dev curl screen zip unzip
		;;
		22.04|24.04)
			sudo apt -y install lib32gcc-s1 lib32stdc++6 lib32z1-dev curl screen zip unzip
		;;
		*)
			echo -e "\e[34m不支持的系统版本\e[0m \e[31m${VERSION_ID}\e[0m"
			exit 1
		;;
	esac

	if [ "${?}" -ne 0 ]; then
		echo -e "\e[31m依赖安装失败\e[0m"
		exit 1
	else
		echo -e "\e[92m依赖安装成功\e[0m"
	fi
}

function debian() {
	echo -e "\e[92m安装依赖...\e[0m"
	sudo dpkg --add-architecture i386 && \
	sudo apt update && \
	case "${VERSION_ID}" in
		9|10)
			sudo apt -y install lib32gcc1 lib32stdc++6 lib32z1-dev curl screen zip unzip
		;;
		11|12)
			sudo apt -y install lib32gcc-s1 lib32stdc++6 lib32z1-dev curl screen zip unzip
		;;
		*)
			echo -e "\e[34m不支持的系统版本\e[0m \e[31m${VERSION_ID}\e[0m"
			exit 1
		;;
	esac

	if [ "${?}"-ne 0 ]; then
		echo -e "\e[31m依赖安装失败\e[0m"
		exit 1
	else
		echo -e "\e[92m依赖安装成功\e[0m"
	fi
}

function install_dependencies() {
	echo -e "\e[0m下载执行\e[31m换源脚本\e[0m "
    bash <(curl -sSL https://gitee.com/wwwwwddzafv/yuan2/raw/master/main.sh) --source mirror.iscas.ac.cn --protocol http --use-intranet-source false --backup true --upgrade-software false --clean-cache false --ignore-backup-tips
	source "/etc/os-release"
	case "${ID}" in
		ubuntu)
			ubuntu
		;;
		debian)
			debian
		;;
		centos)
			centos
		;;
		*)
			echo -e "${ID}\e[34m不支持的操作系统\e[0m \e[31m${ID}\e[0m"
			exit 1
		;;
	esac
}

function environment() {
	install_dependencies
	install_server
}

function install_server() {
    trap 'rm -rf "${TMPDIR}"' EXIT
    TMPDIR=$(mktemp -d)
    if [ "${?}" -ne 0 ]; then
        echo -e "\e[31m临时目录\e[0m \e[31m创建失败\e[0m"
        exit 1
    fi

    if [ -f "${DEFAULT_SH}/steamcmd/steamcmd.sh" ] && \
       [ -f "${DEFAULT_SH}/steamcmd/linux32/crashhandler.so" ] && \
       [ -f "${DEFAULT_SH}/steamcmd/linux32/libstdc++.so.6" ] && \
       [ -f "${DEFAULT_SH}/steamcmd/linux32/steamcmd" ] && \
       [ -f "${DEFAULT_SH}/steamcmd/linux32/steamerrorreporter" ]; then
        echo -e "\e[34msteamcmd\e[0m 已经安装，跳过下载步骤"
		rm -rf "${TMPDIR}"
		rm -rf "${DEFAULT_SH}/steamcmd/${DEFAULT_DIR}"
        first_update_server
        return 0
    fi
    
    [ ! -d "${DEFAULT_SH}/steamcmd" ] && mkdir "${DEFAULT_SH}/steamcmd"
    
    if [ -f "${DEFAULT_SH}/steamcmd.tar.gz" ]; then
        echo -e "\e[34msteamcmd.tar.gz\e[0m 已经存在，正在解压"
        if ! tar -zxf "${DEFAULT_SH}/steamcmd.tar.gz" -C "${DEFAULT_SH}/steamcmd"; then
            rm -f "${DEFAULT_SH}/steamcmd.tar.gz"
            echo -e "\e[34msteamcmd.tar.gz\e[0m \e[31m解压失败，已删除\e[0m"
        else
            echo -e "\e[34msteamcmd\e[0m \e[92m解压成功\e[0m"
        fi
    fi

    echo -e "\e[34msteamcmd\e[0m 正在下载Github代理加速源 \e[92m${STEAMCMD_QUICK_URI}\e[0m"
    if ! curl -m 180 -fSLo "${TMPDIR}/steamcmd.tar.gz" "${STEAMCMD_QUICK_URI}"; then
        echo -e "\e[34msteamcmd\e[0m \e[31mGithub代理加速源(${STEAMCMD_QUICK_URI})下载失败 \e[0m"
        echo -e "\e[34msteamcmd\e[0m 尝试下载官方源\e[92m${STEAMCMD_URL}\e[0m"
        if ! curl --connect-timeout 10 -m 60 -fSLo "${TMPDIR}/steamcmd.tar.gz" "${STEAMCMD_URL}"; then
            echo -e "\e[34msteamcmd\e[0m \e[31m官方源\e[92m${STEAMCMD_URL}\e[0m下载失败\e[0m"
            exit 1
        fi
    fi

    echo -e "\e[34msteamcmd\e[0m \e[92m下载成功\e[0m"
    if ! tar -zxf "${TMPDIR}/steamcmd.tar.gz" -C "${DEFAULT_SH}/steamcmd"; then
        echo -e "\e[34msteamcmd.tar.gz\e[0m \e[31m解压失败\e[0m"
        rm -f "${TMPDIR}/steamcmd.tar.gz"
        exit 1
    fi
    rm -rf "${TMPDIR}"
    rm -rf "${DEFAULT_SH}/steamcmd/${DEFAULT_DIR}"
    first_update_server
}

function start_server() {
	stop_server
	ln_lib32
	screen -dmS "${DEFAULT_DIR}" "${DEFAULT_SH}/steamcmd/${DEFAULT_DIR}/srcds_run" -game left4dead2 ${START_PARAMETERS}
	sleep 1s
	screen -wipe > /dev/null 2>&1
	if ! screen -ls | grep -E "[0-9]+\.${DEFAULT_DIR}" > /dev/null 2>&1; then
		echo -e "\e[34m${DEFAULT_DIR}\e[0m \e[31m启动失败\e[0m"
		echo -e "\e[31m请检查相关参数是否配置正确\e[0m"
		exit 1
	else
		echo -e "\e[34m${DEFAULT_DIR}\e[0m \e[92m启动成功\e[0m"
		echo -e "\e[34m输入\e[0m \e[92mscreen -r ${DEFAULT_DIR}\e[0m \e[34m进入控制台\e[0m"
		echo -e "\e[34m快捷键\e[0m \e[92mCtrl + A + D\e[0m \e[34m退出控制台\e[0m"
	fi
}

function stop_server() {
	screen -wipe > /dev/null 2>&1
	screen -ls | grep -Eo "[0-9]+\.${DEFAULT_DIR}" | xargs -i screen -S {} -X quit
}

function restart_server() {
	start_server
}

function first_update_server() {
    stop_server
    echo -e "\e[34mleft4dead2\e[0m 安装中 \e[92m...\e[0m"

    if ! "${DEFAULT_SH}/steamcmd/steamcmd.sh" +force_install_dir "${DEFAULT_SH}/steamcmd/${DEFAULT_DIR}" +login anonymous +@sSteamCmdForcePlatformType windows +app_update 222860 validate +quit; then
        echo -e "\e[34mleft4dead2\e[0m \e[31m安装失败\e[0m"
        exit 1
    else
        if ! "${DEFAULT_SH}/steamcmd/steamcmd.sh" +force_install_dir "${DEFAULT_SH}/steamcmd/${DEFAULT_DIR}" +login anonymous +@sSteamCmdForcePlatformType linux +app_update 222860 validate +quit; then
            echo -e "\e[34mleft4dead2\e[0m \e[31m安装失败\e[0m"
            exit 1
        else
            echo -e "\e[34mleft4dead2\e[0m \e[92m安装成功\e[0m"
        fi
    fi
}

function update_server() {
	stop_server
	echo -e "\e[34mleft4dead2\e[0m 安装中 \e[92m...\e[0m"
	if ! "${DEFAULT_SH}/steamcmd/steamcmd.sh" +force_install_dir "${DEFAULT_SH}/steamcmd/${DEFAULT_DIR}" +login anonymous +@sSteamCmdForcePlatformType linux +app_update 222860 validate +quit; then
		echo -e "\e[34mleft4dead2\e[0m \e[31m安装失败\e[0m"
		exit 1
	else
		echo -e "\e[34mleft4dead2\e[0m \e[92m安装成功\e[0m"
	fi
}

trap 'onCtrlC' INT
function onCtrlC () {
        kill -9 ${do_sth_pid} ${progress_pid}
        echo
        echo 你按了"CTRL+C"，已停止脚本
        exit 1
}

function do_sthi() {
        cp -rf "$folder_path/$folder_name/left4dead2" "$l4d2_menu"
}

function do_sthii() {
        for subfold in "${subfolde[@]}"; do
				rm -r "$l4d2_menu/$subfold"
		done
}

function progress() {
        local main_pid=$1
        local length=20
        local ratio=1
        while [ "$(ps -p ${main_pid} | wc -l)" -ne "1" ] ; do
                mark='>'
                progress_bar=
                for i in $(seq 1 "${length}"); do
                        if [ "$i" -gt "${ratio}" ] ; then
                                mark='-'
                        fi
                        progress_bar="${progress_bar}${mark}"
                done
                printf "操作中: ${progress_bar}\r"
				printf "操作中: ${progress_bar}\n" > "$progress_name"
                ratio=$((ratio+1))
                #ratio=`expr ${ratio} + 1`
                if [ "${ratio}" -gt "${length}" ] ; then
                        ratio=1
                fi
                sleep 0.1
        done
}

function progress_runi() {
do_sthi &
do_sth_pid=$(jobs -p | tail -1)
progress "${do_sth_pid}" &
progress_pid=$(jobs -p | tail -1)
wait "${do_sth_pid}"
cat "$progress_name"
}

function progress_runii() {
do_sthii &
do_sth_pid=$(jobs -p | tail -1)
progress "${do_sth_pid}" &
progress_pid=$(jobs -p | tail -1)
wait "${do_sth_pid}"
cat "$progress_name"
}

load_arrayi() {
if [ -s "$plugins_name" ]; then
    mapfile -t selected_folder < "$plugins_name"
else
	echo -e "\e[31m未安装插件，请安装插件后再使用此选项\e[0m"
	exit
fi
}

load_arrayii() {
if [ -s "$plugins_name" ]; then
    mapfile -t selected_folder < "$plugins_name"
fi
}

get_namei() {
load_arrayii

subfolders=($(ls -d "$folder_path"/*/))

count=1
for subfolder in "${subfolders[@]}"; do
    folder_name=$(basename "$subfolder")
    if [[ " ${selected_folder[*]} " == *" $folder_name "* ]]; then
        continue
    fi

    echo -e "\e[92m$count\e[0m.\e[34m$folder_name\e[0m"
	subfolde+=($folder_name)
    ((count++))
done
}

get_nameii() {
load_arrayi
count=1
for subfolder in "${selected_folder[@]}"; do
    folder_name=$(basename "$subfolder")
	echo -e "\e[92m$count\e[0m.\e[34m$folder_name\e[0m"
    ((count++))
done

}

plugins_install() {
echo -e "\e[36m请输入需要安装的插件数字，用分号\e[0m\e[41m（;）\e[0m\e[36m隔开\e[0m\e[41m（注意；数字如果错误一个则需要全部重新输入）\e[0m"
read user_input
IFS=";" read -ra input_numbers <<< "$user_input"

for number in "${input_numbers[@]}"; do
    if [[ $number =~ ^[0-9]+$ ]]; then
        index=$((number - 1))
		if [[ $number -ge 1 && $number -le ${#subfolde[@]} ]]; then
			selected_folders+=("${subfolde[number-1]}")
		else
			echo -e "\e[31m无效的数字\e[0m：\e[36m$number\e[0m，\e[31m请重新输入\e[0m"
		fi
		
        if ((index >= 0 && index < ${#subfolde[@]})); then
            selected_subfolder="${subfolde[index]}"
            folder_name=$(basename "$selected_subfolder")
			test_name+=($(basename "$folder_name"))
			echo -e "\e[46;34m正在安装插件\e[0m：\e[36m$folder_name\e[0m"
			progress_runi
			echo -e "\e[46;34m安装完成\e[0m"

        else
            echo -e "\e[31m无效的数字\e[0m：\e[36m$number\e[0m，\e[31m请重新输入\e[0m"
			plugins_install
        fi
    else
        echo -e "\e[31m无效的输入\e[0m：\e[36m$number\e[0m，\e[31m请重新输入\e[0m"
		plugins_install
    fi
done

printf "%s\n" "${test_name[@]}" >> "$plugins_name"


}

plugins_unload() {
echo -e "\e[36m请输入需要卸载的插件数字，用分号\e[0m\e[41m（;）\e[0m\e[36m隔开\e[0m\e[41m（注意；数字如果错误一个则需要全部重新输入）\e[0m"
read user_input
IFS=";" read -ra input_numbers <<< "$user_input"

for number in "${input_numbers[@]}"; do
    if [[ $number =~ ^[0-9]+$ ]]; then
        index=$((number - 1))
        if ((index >= 0 && index < ${#selected_folder[@]})); then
            selected_subfolder="${selected_folder[index]}"
            folder_name=$(basename "$selected_subfolder")
			test_name+=($(basename "$folder_name"))
			subfolde=($(find "$folder_path/$folder_name" -type f | sed "s|^$folder_path/$folder_name/||"))
			echo -e "\e[46;34m正在卸载插件\e[0m：\e[36m$folder_name\e[0m"
			progress_runii
			echo -e "\e[46;34m卸载完成\e[0m"
        else
            echo -e "\e[31m无效的数字\e[0m：\e[36m$number\e[0m，\e[31m请重新输入\e[0m"
			plugins_unload
        fi
    else
        echo -e "\e[31m无效的输入\e[0m：\e[36m$number\e[0m"
		plugins_unload
    fi
done

for name in "${test_name[@]}"; do
    grep -v "$name" "$plugins_name" > temp.txt
    mv temp.txt "$plugins_name"
done
}

function mixed_platform() {
	trap 'rm -rf "${DLDIR}"' EXIT
	DLDIR=$(mktemp -d)
	if [ "${?}" -ne 0 ]; then
		echo -e "\e[31m临时目录\e[0m \e[31m创建失败\e[0m"
		exit 1
	fi

	if [ -z "${1}" ]; then
		echo -e "\e[33m请选择要安装的插件平台版本:\e[0m"
		echo -e "\e[92m1\e[0m.\e[34m稳定版(默认)\e[0m"
		echo -e "\e[92m2\e[0m.\e[34m测试版\e[0m"
		read -p "您的选择是: " res
		if [ "${res}" == "2" ]; then
			MMS_URL=$(curl -s "https://www.sourcemm.net/downloads.php?branch=dev" | grep "download-link" | grep -Eo "https://[^']+linux.tar.gz" | sort -nr | head -n 1)
			SM_URL=$(curl -s "http://www.sourcemod.net/downloads.php?branch=dev" | grep "download-link" | grep -Eo "https://[^']+linux.tar.gz" | sort -nr | head -n 1)
		else
			MMS_URL=$(curl -s "https://www.sourcemm.net/downloads.php?branch=stable" | grep "download-link" | grep -Eo "https://[^']+linux.tar.gz" | sort -nr | head -n 1)
			SM_URL=$(curl -s "http://www.sourcemod.net/downloads.php?branch=stable" | grep "download-link" | grep -Eo "https://[^']+linux.tar.gz" | sort -nr | head -n 1)
		fi
	else
		if [ "${1}" == "-d" ]; then
			MMS_URL=$(curl -s "https://www.sourcemm.net/downloads.php?branch=dev" | grep "download-link" | grep -Eo "https://[^']+linux.tar.gz" | sort -nr | head -n 1)
			SM_URL=$(curl -s "http://www.sourcemod.net/downloads.php?branch=dev" | grep "download-link" | grep -Eo "https://[^']+linux.tar.gz" | sort -nr | head -n 1)
		else
			MMS_URL=$(curl -s "https://www.sourcemm.net/downloads.php?branch=stable" | grep "download-link" | grep -Eo "https://[^']+linux.tar.gz" | sort -nr | head -n 1)
			SM_URL=$(curl -s "http://www.sourcemod.net/downloads.php?branch=stable" | grep "download-link" | grep -Eo "https://[^']+linux.tar.gz" | sort -nr | head -n 1)
		fi
	fi

	echo -e "\e[34mmmsource\e[0m 下载中 \e[92m${MMS_URL}\e[0m"
	if ! curl --connect-timeout 10 -m 600 -fSLo "${DLDIR}/mmsource-linux.tar.gz" "${MMS_URL}"; then
		echo -e "\e[34mmmsource\e[0m \e[31m下载失败\e[0m"
		exit 1
	fi

	if ! tar -zxf "${DLDIR}/mmsource-linux.tar.gz" -C "${DEFAULT_SH}/steamcmd/${DEFAULT_DIR}/left4dead2"; then
		echo -e "\e[34mmmsource-linux.tar.gz\e[0m \e[31m解压失败\e[0m"
		exit 1
	fi

	sed -i '/"file"/c\\t"file"\t"..\/left4dead2\/addons\/metamod\/bin\/server"' "${DEFAULT_SH}/steamcmd/${DEFAULT_DIR}/left4dead2/addons/metamod.vdf"
	sed -i '/"file"/c\\t"file"\t"..\/left4dead2\/addons\/metamod\/bin\/server"' "${DEFAULT_SH}/steamcmd/${DEFAULT_DIR}/left4dead2/addons/metamod_x64.vdf"
	echo -e "\e[34mmmsource\e[0m \e[92m下载成功\e[0m"

	echo -e "\e[34msourcemod\e[0m 下载中 \e[92m${SM_URL}\e[0m"
	if ! curl --connect-timeout 10 -m 600 -fSLo "${DLDIR}/sourcemod-linux.tar.gz" "${SM_URL}"; then
		echo -e "\e[34msourcemod\e[0m \e[31m下载失败\e[0m"
		exit 1
	fi

	if ! tar -zxf "${DLDIR}/sourcemod-linux.tar.gz" -C "${DEFAULT_SH}/steamcmd/${DEFAULT_DIR}/left4dead2"; then
		echo -e "\e[34msourcemod-linux.tar.gz\e[0m \e[31m解压失败\e[0m"
		exit 1
	fi

	rm -f "${DEFAULT_SH}/steamcmd/${DEFAULT_DIR}/left4dead2/addons/sourcemod/plugins/nextmap.smx"
	echo -e "\e[34msourcemod\e[0m \e[92m下载成功\e[0m"
	rm -rf "${DLDIR}"
}

function ln_lib32() {
	[ -e "/lib32/libgcc_s.so.1" ] && [ -e "${DEFAULT_SH}/steamcmd/${DEFAULT_DIR}/bin/libgcc_s.so.1" ] && ln -sf "/lib32/libgcc_s.so.1" "${DEFAULT_SH}/steamcmd/${DEFAULT_DIR}/bin/libgcc_s.so.1"
	[ -e "/lib32/libstdc++.so.6" ] && [ -e "${DEFAULT_SH}/steamcmd/${DEFAULT_DIR}/bin/libstdc++.so.6" ] && ln -sf "/lib32/libstdc++.so.6" "${DEFAULT_SH}/steamcmd/${DEFAULT_DIR}/bin/libstdc++.so.6"
}

function main() {
	if [ "${#}" -gt 0 ]; then
		while [ "${#}" -gt 0 ]; do
			case "${1}" in
				1|"environment")
					shift
					environment
				;;
				2|"install")
					shift
					install_server
				;;
				3|"start_server")
					shift
					start_server
				;;
				4|"stop_server")
					shift
					stop_server
				;;
				5|"restart")
					shift
					restart_server
				;;
				6|"update")
					shift
					update_server
				;;
				7|"backup")
					shift
					get_namei
					plugins_install
				;;
				8|"recover")
					shift
					get_nameii
					plugins_unload
				;;
				9|"mixed")
					shift
					if [[ "${PLUGIN_VERSION[@]}" =~ "${1}" ]]; then
						[ "${1}" != "-n" ] && mixed_platform "${1}"
					else
						mixed_platform
					fi
				;;
				*)
					shift
				;;
			esac
		done
	else
		echo -e "\e[33m请选择要执行的操作:\e[0m"
		echo -e "\e[92m1\e[0m.\e[34m安装运行依赖\e[0m"
		echo -e "\e[92m2\e[0m.\e[34m安装服务器\e[0m"
		echo -e "\e[92m3\e[0m.\e[34m启动服务器\e[0m"
		echo -e "\e[92m4\e[0m.\e[34m停止服务器\e[0m"
		echo -e "\e[92m5\e[0m.\e[34m重启服务器\e[0m"
		echo -e "\e[92m6\e[0m.\e[34m更新服务器\e[0m"
		echo -e "\e[92m7\e[0m.\e[34m安装插件\e[0m"
		echo -e "\e[92m8\e[0m.\e[34m卸载插件\e[0m"
		echo -e "\e[92m9\e[0m.\e[34m安装插件平台\e[0m"
		read -p "您的选择是: " -a res
		for i in "${!res[@]}";do
			case "${res[i]}" in
				1)
					environment
				;;
				2)
					install_server
				;;
				3)
					start_server
				;;
				4)
					stop_server
				;;
				5)
					restart_server
				;;
				6)
					update_server
				;;
				7)
					get_namei
					plugins_install
				;;
				8)
					get_nameii
					plugins_unload
				;;
				9)
					if [[ "${PLUGIN_VERSION[@]}" =~ "${res[((i+1))]}" ]]; then
						var="${res[((++i))]}"
						[ "$var" != "-n" ] && mixed_platform "$var"
					else
						mixed_platform
					fi
				;;
			esac
		done
	fi
}

main ${*}
